﻿namespace KingerRobot.MexicoSailunMDC.SpiService;
internal interface IRcsLocation
{
    /// <summary>
    /// 获得所有库位
    /// </summary>
    /// <returns></returns>
    List<PORcsLocation> GetLocations();
    /// <summary>
    /// 通过位置ID获取位置信息
    /// </summary>
    /// <param name="id">位置Id</param>
    /// <returns>位置信息</returns>
    PORcsLocation GetLocationById(long id);

    List<PORcsLocation> GetLocationByCrnId(long crnId);

    List<PORcsLocation> GetLoctionByLocCode(string locCode);
    /// <summary>
    /// 获取硫化位的下个位置(跑空车用)
    /// </summary>
    /// <param name="locId"></param>
    /// <returns></returns>
    PORcsLocation GetNextCuringLoc(long locId);

    /// <summary>
    /// 通过位置ID获取位置是否存在
    /// </summary>
    /// <param name="id">位置Id</param>
    /// <returns>true:存在；false:不存在</returns>
    bool HasLocationById(long id);

    /// <summary>
    /// 修改库位可用性，包括禁用信息
    /// </summary>
    /// <param name="param"></param>
    /// <returns></returns>
    int ChangeLocEnable(long id, string remark);
    /// <summary>
    /// 修改货位有任务
    /// </summary>
    /// <param name="locId"></param>
    /// <param name="taskId"></param>
    /// <returns></returns>
    int UpdateLocationHasTask(long locId, long taskId, long skuId);
    /// <summary>
    /// 清除库位绑定信息
    /// </summary>
    /// <param name="locId">库位ID</param>
    /// <returns></returns>
    int ClearLocationHasTask(long locId);
    /// <summary>
    /// 清除已绑定的 taskId
    /// </summary>
    /// <param name="taskId"></param>
    /// <returns></returns>
    int ClearLocationHasTaskByTaskId(long taskId);
    /// <summary>
    /// 通过位置和taskId 获取对象
    /// </summary>
    /// <param name="taskId"></param>
    /// <param name="locId"></param>
    /// <returns></returns>
    PORcsLocation GetLocTaskIdByLocIdAndTaskId(long taskId, long locId);

    /// <summary>
    /// 修改货位：根据参数修改成有货/无货
    /// </summary>
    /// <param name="materialId">物料Id</param>
    /// <param name="startLocId">开始为：0 不修改[修改无货]</param>
    /// <param name="targetLocId">结束为：0 不修改[修改有货]</param>
    /// <returns></returns>
    int UpdateLocationHasSku(long? materialId, DateTime? mdTime, long? startLocId = 0, long? targetLocId = 0);

    /// <summary>
    /// 修改货位和货位跟踪(skuId)
    /// </summary>
    /// <param name="skuId">单元ID</param>
    /// <param name="startLocId">开始 清除</param>
    /// <param name="targetLocId">目标 添加</param>
    /// <returns></returns>
    int UpdateLocationAndWcsLocWithSkuId(long? skuId, long? startLocId = 0, long? targetLocId = 0, bool isDelTarget = false);
    /// <summary>
    /// 修改货位和货位跟踪(taskId)
    /// </summary>
    /// <param name="taskId">任务ID</param>
    /// <param name="startLocId">开始</param>
    /// <param name="targetLocId">目标</param>
    /// <returns></returns>
    int UpdateLocationAndWcsLocWithTaskId(long? taskId, long? startLocId = 0, long? targetLocId = 0);
    /// <summary>
    /// 查找所有可用库位
    /// </summary>
    /// <returns></returns>
    List<PORcsLocation> GetAllLocations();
    /// <summary>
    /// 查找所有可用硫化位
    /// </summary>
    /// <returns></returns>
    public List<PORcsLocation> GetAllCuringLocations();
    /// <summary>
    /// 查找所有可用库位
    /// </summary>
    /// <returns></returns>
    List<PORcsLocation> GetAllLocationsISLoc();
    /// <summary>
    /// 查找所有可用库位——优化后用次方法 2025-03-26
    /// </summary>
    /// <returns></returns>
    List<PORcsLocation> GetAllLocationsOutISLoc();

    /// <summary>
    /// 查找所有可用无货高胎库位
    /// </summary>
    /// <returns></returns>
    List<PORcsLocation> GetAllNoHaveHighLocationsISLoc();
    /// <summary>
    /// 查找所有可用无货库位
    /// </summary>
    /// <returns></returns>
    List<PORcsLocation> GetAllNoHasLocationsISLoc();
    /// <summary>
    /// 通过类型查找
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    List<PORcsLocation> GetAllLocationsByType(int type);
    /// <summary>
    /// 获取所有货位的taskid
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    List<long> GetAllLocationTaskIdByType(int type);
    /// <summary>
    /// 根据库位类型查找所有有货库位
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    List<PORcsLocation> GetHasSkuLocationsByType(int type);
    /// <summary>
    /// 查找所有可用入库货位（无任务）
    /// </summary>
    /// <returns></returns>
    List<PORcsLocation> GetAllInNoTaskLocations();

    List<PORcsLocation> GetAllInNoTaskLocationsV2();
    /// <summary>
    /// 查找所有可出库货位（无任务）
    /// </summary>
    /// <returns></returns>
    List<PORcsLocation> GetAllOutNoTaskLocations();

    List<PORcsLocation> GetAllOutNoTaskLocationsV2();
    /// <summary>
    /// 生成出库任务用
    /// </summary>
    /// <returns></returns>
    List<OutLocationNoTaskBean> GetAllOutNoTaskLocationsV3(int locType);
    /// <summary>
    /// 查找所有可出库货位（无任务）
    /// </summary>
    /// <returns></returns>
    List<long> GetGoodLocs();
    /// <summary>
    /// 查找无放货货位
    /// </summary>
    /// <returns></returns>
    List<PORcsLocation> GetNoGoodsLocations();
    /// <summary>
    /// 查找有放货货位
    /// </summary>
    /// <param name="enumInStockType">[0:入库（默认）；1：出库]</param>
    /// <returns></returns>
    List<PORcsLocation> GetInStockLocations(EnumInStockType enumInStockType);

    /// <summary>
    /// 查找有放货货位无货货位
    /// </summary>
    /// <returns></returns>
    LocationHasBean GetHasSkuLocations();

    /// <summary>
    /// 获取堆垛机负责的空货位
    /// </summary>
    /// <param name="crnForkInfos"></param>
    /// <returns></returns>
    List<LocationInfo> GetNoGoodsLocation(List<CrnForkInfo> crnForkInfos);

    /// <summary>
    /// 获取堆垛机负责的空货位
    /// </summary>
    /// <param name="crnForkInfos"></param>
    /// <returns></returns>
    //List<LocationInfo> GetNoGoodsLocationByHeight(List<CrnForkInfo> crnForkInfos, decimal height,decimal outSide);
    /// <summary>
    /// 获取堆垛机负责的有货位 汇总
    /// </summary>
    /// <param name="crnForkInfos"></param>
    /// <param name="minute">（分钟）</param>
    /// <returns></returns>
    List<LocationGroupInfo> GetGoodsLocationByCrnIdGroup(List<CrnForkInfo> crnForkInfos, int minute);
    /// <summary>
    /// 获取区域负责的有货位 汇总
    /// </summary>
    /// <param name="crnForkInfos"></param>
    /// <param name="minute">（分钟）</param>
    /// <returns></returns>
    List<LocationGroupInfo> GetGoodsLocationByAreaIdGroup(List<CrnForkInfo> crnForkInfos);
    /// <summary>
    /// 获取区域负责的有货位 汇总
    /// </summary>
    /// <param name="crnForkInfos"></param>
    /// <param name="productN"></param>
    /// <returns></returns>
    List<LocationGroupInfo> GetGoodsLocationByAreaIdGroupV2(List<CrnForkInfo> crnForkInfos, List<ProductLocBean> productN, List<POWcsEquipLocHold> wcsEquipLocHolds);
    /// <summary>
    /// 获取所有库存有货位 汇总
    /// </summary>
    /// <param name="crnForkInfos"></param>
    /// <param name="minute"></param>
    /// <returns></returns>
    List<LocationGroupInfo> GetGoodsLocationByLibrarydGroup(List<CrnForkInfo> crnForkInfos, int minute);
    /// <summary>
    /// 获取堆垛机负责的单一空货位
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    List<LocationInfo> GetSingleLocation(List<LocationInfo> pORcsLocations);
    /// <summary>
    /// 获取堆垛机负责的成对空货位
    /// </summary>
    /// <param name="pORcsLocations"></param>
    /// <returns></returns>
    List<LocationInfo> GetDoubleLocation(List<LocationInfo> pORcsLocations);

    List<PORcsLocation> GetDoubleRcsLocation(List<PORcsLocation> locations);
    /// <summary>
    /// 查找单配对库位
    /// </summary>
    /// <param name="pORcsLocations">堆垛机管理的空货位</param>
    /// <param name="materialId">物料</param>
    /// <param name="fork">货叉</param>
    ///  <param name="groupId">组号</param>
    /// <returns></returns>
    LocationInfo GetTagertSingleLoc(List<LocationInfo> pORcsLocations, long? materialId, CrnForkInfo fork,int? groupId);

    /// <summary>
    /// 查找双配对库位
    /// </summary>
    /// <param name="pORcsLocations"></param>
    /// <param name="materialId1"></param>
    /// <param name="materialId2"></param>
    /// <param name="groupId"></param>
    /// <returns></returns>
    (LocationInfo Loc1, LocationInfo Loc2) GetTagertDoubleLoc(List<LocationInfo> pORcsLocations,
     long? materialId1,
     long? materialId2, CrnForkInfo fork1, CrnForkInfo fork2, int? groupId);

    /// <summary>
    /// 通过 Ids 获取位置
    /// </summary>
    /// <param name="locId"></param>
    /// <returns></returns>
    List<PORcsLocation> GetLocationsByLocIds(List<long?> ids);
    /// <summary>
    /// 通过 Ids 获取硫化位
    /// </summary>
    /// <param name="locId"></param>
    /// <returns></returns>
    List<PORcsLocation> GetCuringLocationsByLocIds(List<long?> ids);
    /// <summary>
    /// 修改库位有货
    /// </summary>
    /// <param name="materialId"></param>
    /// <param name="locId"></param>
    /// <returns></returns>
    int UpdateLocationHasGood(long? materialId, long? locId, DateTime? mdTime);

    /// <summary>
    /// 修改库位无货
    /// </summary>
    /// <param name="locId"></param>
    /// <returns></returns>
    int UpdateLocationNoGood(long? locId);


    /// <summary>
    /// 查找符合轮胎大小规格的货位
    /// </summary>
    /// <param name="tireType">轮胎大小规格</param>
    /// <returns></returns>
    List<PORcsLocation> GetTireTypeLocations(int tireType);
    /// <summary>
    /// 修改物料ID
    /// </summary>
    /// <param name="locId"></param>
    /// <param name="mateiralId"></param>
    /// <returns></returns>
    int UpdateLocationMateiralId(long locId, long mateiralId);
    /// <summary>
    /// 任务已创建修改
    /// </summary>
    /// <param name="id"></param>
    /// <param name="productCode"></param>
    /// <param name="taskId"></param>
    /// <returns></returns>
    int UpdateLocTaskId(long id, string productCode, long taskId, string remark);

    /// <summary>
    /// 禁用库位入库不可用
    /// </summary>
    /// <param name="id"></param>
    /// <param name="remark"></param>
    /// <returns></returns>
    int UpdateTestInEnableRemark(long id, string remark);
    /// <summary>
    /// 修改库位禁用
    /// </summary>
    /// <param name="productCode"></param>
    /// <param name="remark"></param>
    /// <returns></returns>
    int UpdateCrnLocEnableRemark(string productCode, string remark);
    /// <summary>
    /// 修改位置条码
    /// </summary>
    /// <param name="locId"></param>
    /// <param name="productCode"></param>
    /// <returns></returns>
    int UpdateLocationProductCode(long locId, string productCode);
    /// <summary>
    /// 通过locid获取当前仓库id
    /// </summary>
    /// <param name="locId"></param>
    /// <returns></returns>
    long GetWarehouseByLocationID(long locId);
    /// <summary>
    /// 更新LocUnEnable
    /// </summary>
    /// <param name="id"></param>
    /// <param name="taskNo"></param>
    /// <returns></returns>
    int UpdateLocUnEnable(long id, int taskNo = 0);
}

internal class LocationHasBean
{
    /// <summary>
    /// 无货
    /// </summary>
    public List<PORcsLocation> NoGoods { get; set; }
    /// <summary>
    /// 有货
    /// </summary>
    public List<PORcsLocation> InStock { get; set; }
}
internal class OutLocationNoTaskBean
{
    /// 无货
    /// </summary>
    public long? Id { get; set; }
    /// <summary>
    /// 有货
    /// </summary>
    public long? MaterialId { get; set; }
    public DateTime? MdTime { get; set; }
    public long? GroupId { get; set; }
    public int? GroupIndex { get; set; }

}

internal class LocationInfo
{
    public long? Id { get; set; }
    public long? MaterialId { get; set; }
    public long? GroupId { get; set; }
    public int? GroupIndex { get; set; }
    /// <summary>
    /// 是否单货位（没有配对货位【异常也算：单】） true 是
    /// </summary>
    public bool IsSingle { get; set; }
    /// <summary>
    /// 排序
    /// </summary>
    public int? RelateScore { get; set; }
    public DateTime? MdTime { get; set; }
    public long? CrnId { get; set; }
    public CrnForkInfo Fork { get; set; }
    // 出库订单
    public POWmsOutOrderSummary Summary { get; set; }
    /// <summary>
    /// 是否双库位有货
    /// </summary>
    public bool IsDouble { get; set; }
    public long? AreaId { get; set; }
    public decimal? LocHeight { get; set; }
    /// <summary>
    /// 货位轮胎类型 1小胎 2大胎
    /// </summary>
    public int? LocTireType { get; set; }

    /// <summary>
    /// 是否超期 1超时 0未超期
    /// </summary>
    public int IsTimeOut { get; set; }

    public decimal? LocMaxOutsize { get; set; }
    public decimal? LocMinOutsize { get; set; }
    public int? TaskCount { get; set; }
    /// <summary>
    /// 是否配对货位 1是 2否
    /// </summary>
    public int? LocInputType { get; set; }
    
}
internal class LocationGroupInfo
{
    /// <summary>
    /// 堆垛机
    /// </summary>
    public long? CrnId { get; set; }
    /// <summary>
    /// 物料
    /// </summary>
    public long? MaterialId { get; set; }
    /// <summary>
    /// 有货货位生产最小时间
    /// </summary>
    public DateTime? MinTime { get; set; }
    /// <summary>
    /// 是否超期 1超时 0未超期
    /// </summary>
    public int IsTimeOut { get; set; }
    /// <summary>
    /// 所有有货库位
    /// </summary>
    public List<LocationInfo> LocationInfos { get; set; }
}